<template>
  <div class="flex flex-col items-center p-4 bg-pink-50 min-h-screen">
    <h1 class="text-3xl font-bold mb-4">🎡 抓娃娃机</h1>

    <div class="mb-2 text-lg text-pink-600 font-bold">
      剩余时间: {{ timeLeft }} 秒 | 得分: {{ score }} | 已尝试: {{ attempts }}/{{ maxAttempts }}
    </div>

    <div
      ref="game"
      class="relative w-full max-w-8xl h-[600px] bg-orange-50 border-4 border-pink-300 overflow-hidden"
    >
      <!-- 爪子 -->
      <div
        ref="claw"
        class="absolute top-0 w-[50px] transition-left duration-100"
        :style="{ left: clawLeft + 'px' }"
      >
        <div class="w-[4px] bg-gray-300 mx-auto relative" :style="{ height: ropeHeight + 'px' }">
          <div class="absolute bottom-0 left-1/2 -translate-x-1/2 w-5 h-1 bg-gray-500"></div>
        </div>
        <div class="w-[50px] h-[20px] bg-gray-500 rounded mt-1 relative">
          <div
            :class="[
              'absolute bottom-[-10px] w-[15px] h-[15px] bg-gray-500 rounded transition-transform duration-300',
              clawClosed ? 'left-1 rotate-[-30deg]' : 'left-1 rotate-[-15deg]'
            ]"
          ></div>
          <div
            :class="[
              'absolute bottom-[-10px] w-[15px] h-[15px] bg-gray-500 rounded transition-transform duration-300',
              clawClosed ? 'right-1 rotate-[30deg]' : 'right-1 rotate-[15deg]'
            ]"
          ></div>
        </div>

        <!-- 被抓住的娃娃 -->
        <div v-if="caughtDoll" class="absolute bottom-[-30px] left-1/2 -translate-x-1/2 m-0 z-10">
          <span :class="caughtDoll.className">{{ caughtDoll.emoji }}</span>
        </div>
      </div>

      <!-- 娃娃 -->
      <div
        v-for="doll in dolls"
        :key="doll.id"
        :class="['absolute bottom-2 text-center font-bold text-white', doll.className]"
        :style="{ left: doll.left + 'px', width: '50px', height: '50px', lineHeight: '50px' }"
      >
        {{ doll.emoji }}
        <span
          v-if="doll.score > 2"
          class="absolute top-[-10px] right-[-10px] w-5 h-5 text-xs rounded-full bg-pink-500 flex items-center justify-center"
        >
          {{ doll.score }}
        </span>
      </div>
    </div>

    <div class="mt-4 flex flex-col items-center">
      <button
        @click="catchDoll"
        class="px-6 py-2 bg-pink-500 text-white rounded hover:bg-pink-600 mb-2"
      >
        🎁 抓取
      </button>
      <div class="text-gray-500 text-sm">提示：使用键盘 ← → 键左右移动抓手 | 空格键抓取</div>
      <div class="text-gray-500 text-sm">不同娃娃有不同分值！</div>
    </div>

    <audio ref="successSound" preload="auto">
      <source src="/audio/unbelivable.mp3" type="audio/mpeg" />
    </audio>
    <audio ref="failSound" preload="auto">
      <source src="/audio/fail.mp3" type="audio/mpeg" />
    </audio>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'

interface Doll {
  id: number
  left: number
  score: number
  emoji: string
  className: string
}

const game = ref<HTMLDivElement>()
const claw = ref<HTMLDivElement>()
const successSound = ref<HTMLAudioElement>()
const failSound = ref<HTMLAudioElement>()

let clawLeft = ref(0)
let ropeHeight = ref(100)
let clawClosed = ref(false)

let timeLeft = ref(120)
let score = ref(0)
let attempts = ref(0)
const maxAttempts = 5

let dolls = ref<Doll[]>([])
let caughtDoll: Doll | null = null
let dollId = 0

let timer: number
let dollGen: number
let dollMove: number
let isGrabbing = false

const dollTypes = [
  { className: 'bg-pink-400 rounded-full', score: 1, emoji: '🐰' },
  { className: 'bg-sky-300 rounded-[40%_60%_70%_30%/40%_50%_60%_50%]', score: 2, emoji: '🐱' },
  { className: 'bg-green-300 rounded-[30%_70%_50%_50%/30%_30%_70%_70%]', score: 3, emoji: '🐻' },
  { className: 'bg-pink-200 rounded-[50%_50%_40%_60%/60%_40%_50%_50%]', score: 2, emoji: '🐶' },
  { className: 'bg-yellow-100 rounded', score: 4, emoji: '🐼' }
]

onMounted(() => {
  clawLeft.value = (game.value!.clientWidth - 50) / 2
  startGame()

  window.addEventListener('keydown', handleKeyDown)
  window.addEventListener('resize', handleResize)
})

onBeforeUnmount(() => {
  clearInterval(timer)
  clearInterval(dollGen)
  clearInterval(dollMove)
  window.removeEventListener('keydown', handleKeyDown)
  window.removeEventListener('resize', handleResize)
})

function handleKeyDown(e: KeyboardEvent) {
  if (isGrabbing) return
  if (e.key === 'ArrowLeft') moveClaw(-15)
  if (e.key === 'ArrowRight') moveClaw(15)
  if (e.key === ' ') catchDoll()
}

function handleResize() {
  clawLeft.value = (game.value!.clientWidth - 50) / 2
}

function moveClaw(delta: number) {
  const width = game.value!.clientWidth
  clawLeft.value = Math.min(Math.max(0, clawLeft.value + delta), width - 50)
}

function startGame() {
  timer = setInterval(() => {
    timeLeft.value--
    if (timeLeft.value <= 0) {
      endGame(`⏰ 时间到！总分: ${score.value}`)
    }
  }, 1000)

  createDoll()
  dollGen = setInterval(createDoll, 2000)

  dollMove = setInterval(() => {
    dolls.value.forEach((d, index) => {
      d.left -= 2
      if (d.left < -60) dolls.value.splice(index, 1)
    })
  }, 30)
}

let nextDollLeft = 0 // 下一个娃娃的起始位置

function createDoll() {
  const type = dollTypes[Math.floor(Math.random() * dollTypes.length)]
  const spacing = 150 // 每个娃娃之间的固定间距（可以调整）

  // 如果是第一个娃娃，就放到游戏区域外的右侧
  if (nextDollLeft === 0) {
    nextDollLeft = game.value!.clientWidth + 50
  } else {
    nextDollLeft += spacing
  }

  dolls.value.push({
    id: dollId++,
    left: nextDollLeft,
    score: type.score,
    emoji: type.emoji,
    className: type.className
  })
}


function playSound(type: 'success' | 'fail') {
  try {
    if (type === 'success') successSound.value?.play()
    else failSound.value?.play()
  } catch {}
}

function catchDoll() {
  if (isGrabbing || attempts.value >= maxAttempts) return
  isGrabbing = true
  attempts.value++

  let clawBottom = 0
  const dropSpeed = 5
  const riseSpeed = 3
  let caught: Doll | null = null

  const dropInterval = setInterval(() => {
    clawBottom += dropSpeed
    ropeHeight.value = 100 + clawBottom

    // 只在下降到娃娃区域时检查
    if (!caught) {
      const clawCenterX = clawLeft.value + 25
      const clawBottomY = ropeHeight.value // 爪子当前纵向位置（绳子长度）

      dolls.value.forEach((d, index) => {
        // 娃娃位置
        const dollX1 = d.left
        const dollX2 = d.left + 50
        const dollY1 = 450 // 娃娃底部固定在容器底部 (500px 高 - 50px 娃娃高)
        const dollY2 = 500

        // 判断爪子是否进入娃娃矩形区域
        if (
          clawCenterX > dollX1 &&
          clawCenterX < dollX2 &&
          clawBottomY >= dollY1 &&
          clawBottomY <= dollY2
        ) {
          caught = dolls.value.splice(index, 1)[0]
          caughtDoll = caught
          clawClosed.value = true
        }
      })
    }

    if (clawBottom >= 400 || caught) {
      clearInterval(dropInterval)

      if (caught) {
        playSound('success')
        score.value += caught.score
      } else {
        playSound('fail')
      }

      // 上升动画
      const riseInterval = setInterval(() => {
        clawBottom -= riseSpeed
        ropeHeight.value = 100 + clawBottom

        // 如果抓到娃娃，让娃娃跟随爪子上升
        if (caughtDoll) {
          // 让娃娃相对爪子固定在下方
          // Vue 模板里已经通过 v-if caughtDoll 绑定在爪子下方
        }

        if (clawBottom <= 0) {
          clearInterval(riseInterval)
          clawClosed.value = false
          caughtDoll = null
          isGrabbing = false

          if (!caught && attempts.value >= maxAttempts) {
            endGame(`😢 超过 ${maxAttempts} 次未成功抓娃娃，游戏失败！`)
          }
        }
      }, 20)
    }
  }, 20)
}


function endGame(msg: string) {
  clearInterval(timer)
  clearInterval(dollGen)
  clearInterval(dollMove)
  alert(msg)
}
</script>
